<template>
  <el-form :model="form"
           class="gl-form"
           :rules="rules"
           ref="glForm">
    <template v-for="(item, ind) in formLabel"
              v-if="item.show !== false">
      <slot :name="item.outSlot"
            :data="item">
        <el-form-item :label="item.label"
                      :key="ind"
                      :prop="item.prop || ''"
                      :label-width="item.width || labelWidth || '120px'"
                      :class="item.className">
          <!-- 插槽 -->
          <template v-if="typeof item.slot === 'string'">
            <slot :name="item.slot"
                  :data="item"></slot>
          </template>
          <!-- 下拉选项 -->
          <template v-else-if="item.options">
            <el-select :class="item.class"
                       :disabled="item.readonly === true"
                       class="change-state vat"
                       v-model="form[item.prop]"
                       @change="$emit('change', {list: item.options, prop: item.prop})"
                       :filterable="item.filterable === true"
                       :clearable="item.clearable === true"
                       :multiple="item.multiple === true"
                       :placeholder="item.placeholder || '请选择'">
              <el-option v-for="(opt, i) in item.options"
                         :key="i"
                         :label="opt[item.labelKey || 'label']"
                         :value="opt[item.valueKey || 'value']">
              </el-option>
            </el-select>
          </template>
          <!-- 单选框 -->
          <template v-else-if="item.radio">
            <el-radio-group @change="$emit('change', {list: item.options, prop: item.prop})"
                            :class="item.class"
                            v-model="form[item.prop]"
                            :disabled="item.readonly === true">
              <el-radio :key="i"
                        v-for="(e, i) in item.radio"
                        :label="e[item.valueKey || 'value']">{{e[item.labelKey ||
                'label']}}
              </el-radio>
            </el-radio-group>
          </template>
          <!-- 复选框 -->
          <template v-else-if="item.checkbox">
            <el-checkbox-group @change="$emit('change', {list: item.options, prop: item.prop})"
                               :class="item.class"
                               v-model="form[item.prop]"
                               :disabled="item.readonly === true">
              <el-checkbox :key="i"
                           v-for="(e, i) in item.checkbox"
                           :label="e.value">{{e.label}}
              </el-checkbox>
            </el-checkbox-group>
          </template>
          <!-- 上传 -->
          <template v-else-if="item.type === 'upload'">
            <!-- :res="item.res || {file_path: form[item.prop]}" -->
            <gl-upload :data="item.data"
                       :disabled="item.disabled"
                       @success="uploadSucc($event, item.prop,item.limit)"
                       :limit="item.limit"
                       :file-list="form[item.fileList]"
                       :res="form[item.prop]||[]"
                       @removeImg="removeImg($event,item)"
                       @showPreview="showPreview"
                       :type="item.loadType">
            </gl-upload>
          </template>
          <!-- 文本域 -->
          <template v-else-if="item.type === 'textarea' || item.rows">
            <ueditor v-if="item.text === 'ueditor'"
                     :config="item.choconfig || choconfig"
                     v-model="form[item.prop]"></ueditor>
            <el-input type="textarea"
                      v-else
                      :disabled="item.readonly === true"
                      @change="$emit('change', {list: item.options, prop: item.prop})"
                      :rows="item.rows || 3"
                      :placeholder="item.placeholder"
                      :resize="item.resize || 'none'"
                      v-model="form[item.prop]">
            </el-input>
          </template>
          <!-- 时间选择器 -->
          <template v-else-if="item.dateType">
            <el-date-picker v-model="form[item.prop]"
                            @change="$emit('change', {list: item.options, prop: item.prop})"
                            :disabled="item.readonly === true"
                            :type="item.dateType"
                            :value-format="item.valueFormat"
                            :format="item.format"
                            :placeholder="item.placeholder || '选择日期时间'">
            </el-date-picker>
          </template>
          <!-- 计数器 -->
          <template v-else-if="item.type === 'number'">
            <el-input-number :disabled="item.readonly === true"
                             v-model="form[item.prop]"
                             :controls="item.controls === true"
                             @change="$emit('change', {list: item.options, prop: item.prop})"
                             :placeholder="item.placeholder || ''"></el-input-number>
          </template>
          <!-- 文本框 -->
          <template v-else-if="item.type === 'text'">
            <span>{{(item.format || 's%').replace('s%', form[item.prop] !== 0 ? form[item.prop] || item.text || '' : 0)}}</span>
          </template>
          <!-- 默认input输入框 -->
          <template v-else>
            <el-input :class="item.class"
                      :type="item.inputType"
                      :placeholder="item.placeholder"
                      :disabled="item.readonly === true"
                      :maxlength="item.maxlength || ''"
                      :minlength="item.minlength || ''"
                      @change="$emit('change', {list: item.options, prop: item.prop})"
                      v-model="form[item.prop]"></el-input>
          </template>

        </el-form-item>
      </slot>
    </template>
  </el-form>
</template>

<script>
export default {
  name: 'GlForm',
  props: {
    // 绑定的表单对象
    form: {
      type: Object,
      default() {
        return {}
      }
    },
    // 定义表单项
    formLabel: {
      type: Array,
      default() {
        return []
      }
    },
    // 表单项默认宽 为空时默认120px
    labelWidth: {
      type: String,
      default: ''
    },
    choconfig: {
      type: Object,
      default() {
        return { toolbars: [['bold', 'italic', 'underline', 'indent']] }
      }
    },
    // 必填项 'a,b,c,...' || ['a', 'b', 'c',...]
    must: {
      type: String | Array,
      default() {
        return []
      }
    },
    // 其它规则
    rule: {
      type: Object,
      default() {
        return {}
      }
    },
    limit: {
      type: Number | String,
      default: ''
    }
  },
  data() {
    return {
      rules: {}
    }
  },
  watch: {
    must() {
      this.resetFields()
      this.initRules()
    },
    rule() {
      this.resetFields()
      this.initRules()
    },
    formLabel() {
      this.resetFields()
      this.initRules()
    }
  },
  methods: {
    removeImg(val, item) {
      if (item.limit == '1') {
        this.form[item.prop] = ''
      } else {
        this.form[item.prop].map((e, i) => {
          Object.keys(val).map(j => {
            if (e.uid === val[j]) {
            //   console.log(e)
                this.form[item.prop].splice(i, 1)
            }
          })
        })
        // console.log(this.form[item.prop]);
      }
      this.$emit('removeImg', val,item)
    },
    showPreview(file) {
      this.$emit('showPreview', file)
    },
    uploadSucc(res, prop, limit) {
    //   console.log(res)
      if (limit && limit == '1') {
        this.form[prop] = res.file_path
      }
      this.$emit('upload', res, prop)
    },
    initRules() {
      // must
      let must = this.must || []
      if (typeof must === 'string') {
        must = must ? must.split(',') : []
        must = must.map(e => e.replace(/\s/, ''))
      }
      must.map(e => {
        let item = this.formLabel.find(it => it.prop === e)
        if (item) {
          this.rules[e] = [
            { required: true, message: `请输入${item.label}`, trigger: 'blur' }
          ]
        }
      })

      // rule
      let rule = { ...this.rule }
      Object.keys(rule).map(k => {
        this.rules[k] = this.rules[k] || []
        this.rules[k].push(...rule[k])
      })

      // formLabel
      let formLabel = this.formLabel.filter(e => e.rule)
      formLabel.map(item => {
        this.rules[item.prop] = this.rules[item.prop] || []
        this.rules[item.prop].push(...item.rule)
      })
    },
    validate() {
      let bool = false
      this.$refs.glForm.validate(res => {
        bool = res
      })
      return bool
    },
    resetFields(callback) {
      this.$refs.glForm.resetFields()
    },
    clearValidate() {
      this.$refs.glForm.clearValidate()
    }
  },
  created() {
    this.initRules()
  }
}
</script>

<style lang='less' scoped>
.orderIpt {
  width: 320px;
}

.gl-form {
  .el-form-item {
    margin-bottom: 18px;
  }
  /deep/ .el-form-item__label,
  /deep/ .el-input__inner {
    height: 30px;
    line-height: 30px;
  }
  /deep/ .el-form-item__content,
  /deep/ .el-input__icon {
    line-height: 30px;
  }
  /deep/ .el-form-item__error {
    padding-top: 2px;
  }
}
</style>
